#include "include/play_manager.h"
namespace codec {
PlayManager::PlayManager() { pools->start(); }
void preciseSleep(int64_t micros) {
  if (micros <= 0) return;

  struct timespec req {
    .tv_sec = micros / 1000000, .tv_nsec = (micros % 1000000) * 1000
  };
  nanosleep(&req, nullptr);  // 纳秒级等待
}

void PlayManager::start() {
  pools->submitTask([this]() {
    __android_log_print(ANDROID_LOG_ERROR, "fhq", "parse tid %d", gettid());
    while (!abort_.load(std::memory_order_acquire)) {
      std::unique_lock<std::mutex> lock(paused_mutex_);
      paused_cv_.wait(lock, [this] {
        return !paused_.load(std::memory_order_acquire) ||
               abort_.load(std::memory_order_acquire);
      });
      lock.unlock();

      if (seeking_.load(std::memory_order_acquire)) {
        __android_log_print(ANDROID_LOG_ERROR, "fhq", "parse seek start ");
        std::unique_lock<std::mutex> lock(seek_mutex_);
        parse_cv.wait(lock, [this] {
          return (!seeking_.load() && clearOver()) || abort_.load();
        });
        __android_log_print(ANDROID_LOG_ERROR, "fhq", "parse seek over ");
        lock.unlock();
        continue;  // 跳转后重新开始循环
      }
      AVPacket* packet = parse_->readNextPacket();
      if (!packet) {
        __android_log_print(ANDROID_LOG_ERROR, "fhq", "packet over");
        break;
      }  // 流结束
      if (abort_) {
        av_packet_free(&packet);
        video_packet_queue.push(nullptr);
        audio_packet_queue.push(nullptr);
        break;
      }

      AVRational audio_time_base = {1, audioCodec_->getSampleRate()};
      const int64_t video_pts_us = av_rescale_q(
          packet->pts, parse_->getVideoTimeBase(), audio_time_base);
      double currentPlayingtime =
          static_cast<double>(video_pts_us) / audio_time_base.den;
      if (packet->stream_index == parse_->getVideoStreamIndex()) {
        video_packet_queue.push(packet);
      } else if (packet->stream_index == parse_->getAudioStreamIndex()) {
        audio_packet_queue.push(packet);
      } else {
        av_packet_free(&packet);  // 释放非音视频包
      }
    }
    video_packet_queue.push(nullptr);
    audio_packet_queue.push(nullptr);
  });

  pools->submitTask([this]() {
    __android_log_print(ANDROID_LOG_ERROR, "fhq", "VIDEO PASE parse tid %d",
                        gettid());
    while (!abort_.load(std::memory_order_acquire)) {
      std::unique_lock<std::mutex> lock(paused_mutex_);
      paused_cv_.wait(lock, [this] {
        return !paused_.load(std::memory_order_acquire) ||
               abort_.load(std::memory_order_acquire);
      });
      lock.unlock();
      AVPacket* packet;
      video_packet_queue.pop(packet);
      if (seeking_.load(std::memory_order_acquire)) {
        __android_log_print(ANDROID_LOG_ERROR, "fhq", "video  seek start %zu",
                            video_packet_queue.size());
        // 丢弃当前解码操作
        av_packet_free(&packet);

        // 等待跳转完成
        std::unique_lock<std::mutex> lock(seek_mutex_);
        seek_cv_.wait(lock,
                      [this] { return !seeking_.load() || abort_.load(); });
        __android_log_print(ANDROID_LOG_ERROR, "fhq", "video  seek over %zu",
                            video_packet_queue.size());
        lock.unlock();
        continue;
      }
      if (!packet) break;
      if (abort_) {
        av_packet_free(&packet);
        video_frame_queue.push(nullptr);
        break;
      }
      if (videoCodec_->sendPacket(packet)) {
        while (AVFrame* frame = videoCodec_->receiveFrame()) {
          video_frame_queue.push(av_frame_clone(frame));  // 克隆帧入队
          av_frame_free(&frame);
        }
      }
      av_packet_free(&packet);
    }
    video_frame_queue.push(nullptr);  // 通知渲染线程结束
  });

  pools->submitTask([this]() {
    __android_log_print(ANDROID_LOG_ERROR, "fhq", "AUDIO PASE parse tid %d",
                        gettid());
    while (!abort_.load(std::memory_order_acquire)) {
      std::unique_lock<std::mutex> lock(paused_mutex_);
      audio_cv_.wait(lock, [this] {
        return !paused_.load(std::memory_order_acquire) ||
               abort_.load(std::memory_order_acquire);
      });
      paused_cv_.notify_all();
      lock.unlock();
      AVPacket* packet;
      audio_packet_queue.pop(packet);
      if (seeking_.load(std::memory_order_acquire)) {
        // 丢弃当前解码操作
        av_packet_free(&packet);
        // 等待跳转完成
        std::unique_lock<std::mutex> lock(seek_mutex_);
        seek_cv_.wait(lock,
                      [this] { return !seeking_.load() || abort_.load(); });
        lock.unlock();
        continue;
      }
      if (!packet) break;  // 结束信号
      if (abort_) {
        av_packet_free(&packet);
        break;
      }
      if (audioCodec_->sendPacket(packet)) {
        while (AVFrame* frame = audioCodec_->receiveFrame()) {
          audioCodec_->swrController(frame);
          av_frame_free(&frame);
        }
      }
      av_packet_free(&packet);
    }
  });

  // ====== 4. 视频渲染线程 ======
  pools->submitTask([this]() {
    __android_log_print(ANDROID_LOG_ERROR, "fhq", "VIDEO RENDOR parse tid %d",
                        gettid());
    while (!abort_.load(std::memory_order_acquire)) {
      std::unique_lock<std::mutex> lock(paused_mutex_);
      paused_cv_.wait(lock, [this] {
        return !paused_.load(std::memory_order_acquire) ||
               abort_.load(std::memory_order_acquire);
      });
      lock.unlock();
      AVFrame* frame;
      video_frame_queue.pop(frame);
      if (seeking_.load(std::memory_order_acquire)) {
        // 丢弃当前解码操作
        av_frame_free(&frame);

        // 等待跳转完成
        std::unique_lock<std::mutex> lock(seek_mutex_);
        seek_cv_.wait(lock,
                      [this] { return !seeking_.load() || abort_.load(); });
        lock.unlock();
        continue;
      }
      if (!frame) {  // 结束信号
        onInternalProgressUpdated(1.00, parse_->getDuration());
        break;
      }
      if (abort_) {
        av_frame_free(&frame);
        break;
      }
      // 1. 转换视频PTS到统一时间基
      // 获取音频流的真实时间基（非硬件参数）
      AVRational audio_time_base = {1, audioCodec_->getSampleRate()};
      const int64_t video_pts_us =
          av_rescale_q(frame->pts, parse_->getVideoTimeBase(), audio_time_base);
      __android_log_print(ANDROID_LOG_ERROR, "fhq",
                          "frame->pts:%ld：parse_->getVideoTimeBase.den()：%d "
                          "parse_->getVideoTimeBase.num()：%d "
                          "audioCodec_->getSampleRate()：%d",
                          frame->pts, parse_->getVideoTimeBase().den,
                          parse_->getVideoTimeBase().num,
                          audioCodec_->getSampleRate());
      // 2. 获取音频位置
      const int64_t audioPos = audioCodec_->getAudioPosition();
      if (audioPos == -1) {
        continue;
      }
      double currentPlayingtime =
          static_cast<double>(audioPos) / audioCodec_->getSampleRate();

      __android_log_print(ANDROID_LOG_ERROR, "fhq",
                          "currentaudioPlayingtime:%f：lastPlaytime：%f",
                          currentPlayingtime, lastPlaytime_);
      if (currentPlayingtime - lastPlaytime_ > 1 ||
          currentPlayingtime - lastPlaytime_ < 1) {
        onInternalProgressUpdated(currentPlayingtime / parse_->getDuration(),
                                  currentPlayingtime);
        lastPlaytime_ = currentPlayingtime;
      }
      const int32_t sample_rate = audioCodec_->getSampleRate();
      const int64_t videoPos = video_pts_us;
      double currentVideoPlayingtime =
          static_cast<double>(videoPos) / audio_time_base.den;
      __android_log_print(ANDROID_LOG_ERROR, "fhq",
                          "currentVideoPlayingtime:%f",
                          currentVideoPlayingtime);
      const int64_t diff = videoPos - audioPos;
      __android_log_print(ANDROID_LOG_ERROR, "fhq",
                          "videoPos: %zu,audioPos:%zu,diff:%zu", videoPos,
                          audioPos, diff);
      if (diff > 5000 || diff < -5000) {
        audioCodec_->setTarget(currentVideoPlayingtime);
      } else if (diff > 5) {  // 视频超前>5采样
        preciseSleep(diff * 1000000 /
                     audioCodec_->getSampleRate());  // 微秒级等待
        videoRender_->renderFrame(frame);            // 实际渲染
      } else if (diff < -10) {                       // 视频落后>10采样
        // 丢弃帧，不渲染
      } else {
        videoRender_->renderFrame(frame);
      }
      av_frame_free(&frame);
    }
  });
}

void PlayManager::setDataSource(int fd) {
  int safeFd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
  parse_->setDataSource(safeFd);
}

std::map<std::string, std::string> PlayManager::prepare(
    ANativeWindow* window, const std::string& vertexCode,
    const std::string& fragmentCode) {
  parse_->open();
  videoCodec_->init(parse_->getVideoCodecParams());
  audioCodec_->init(parse_->getAudioCodecParams());
  audioCodec_->initAAudio();
  videoRender_->init(window, vertexCode, fragmentCode);
  return parse_->getMessage();
}
void PlayManager::seekTo(float position) {
  __android_log_print(ANDROID_LOG_ERROR, "fhq", "seek start position%f",
                      position);
  seeking_.store(true, std::memory_order_release);
  {
    std::lock_guard<std::mutex> lock(seek_mutex_);
    lastSeekTime = position;
    auto seek_target_us_ = static_cast<int64_t>(position * 1e3);
    video_packet_queue.clear();
    audio_packet_queue.clear();
    video_frame_queue.clear();
    videoCodec_->flush();
    audioCodec_->flush();
    audioCodec_->pause();
    audioCodec_->requestFlush();
    bool flag = parse_->SeekTo(seek_target_us_);
    audioCodec_->restart();
    __android_log_print(ANDROID_LOG_ERROR, "fhq", "seek over flag %d", flag);
  }
  seeking_.store(false, std::memory_order_release);
  parse_cv.notify_one();
}

void PlayManager::changeSurface(int width, int height, bool isFullScreen) {}
void PlayManager::release() {
  abort_.store(true, std::memory_order_release);
  // 向所有队列发送终止信号（nullptr）
  video_packet_queue.push(nullptr);
  audio_packet_queue.push(nullptr);
  video_frame_queue.push(nullptr);
  clearQueues();

  if (parse_) {
    parse_->close();
  }
  if (videoCodec_) {
    videoCodec_->close();
  }
  if (audioCodec_) {
    audioCodec_->close();
  }
  if (videoRender_) {
    videoRender_->release();
  }
}

void PlayManager::clearQueues() {
  // 清空视频包队列
  while (!video_packet_queue.empty()) {
    AVPacket* packet;
    video_packet_queue.pop(packet);
    av_packet_free(&packet);
  }

  // 清空音频包队列
  while (!audio_packet_queue.empty()) {
    AVPacket* packet;
    audio_packet_queue.pop(packet);
    // AVPacket* packet = audio_packet_queue.pop();
    av_packet_free(&packet);
  }

  // 清空视频帧队列
  while (!video_frame_queue.empty()) {
    AVFrame* frame;
    video_frame_queue.pop(frame);
    av_frame_free(&frame);
  }
}

}  // namespace codec